package stud.mpgame.flash;

import flash.display.Sprite;
import flash.events.Event;
import flash.Lib;
import stud.mpgame.flash.scene.ConnectScene;
import stud.mpgame.flash.scene.GameScene;
import stud.mpgame.network.NetworkMonitor;

/**
 * 22.03.2011 23:04
 * @author GreK
 */
		
class Main
{   
    private var protocolVersion:Int;
    private var networkMonitor:NetworkMonitor;
	private var scenes:Hash<IScene>;
	private var currentScene:IScene;
	
	private var prevTime: Int;
	private static var startAppTime:Float;    
    
	private static var instance:Main;
	public static function getInstance():Main {
		if ( instance == null )
			instance = new Main();
			
		return instance;
	}
	
	private function new() {        
        protocolVersion = 1;
        networkMonitor = new NetworkMonitor(Std.int(Date.now().getTime()), protocolVersion);
		scenes = new Hash<IScene>();
		registerScene(new ConnectScene());
		registerScene(new GameScene());
	}
	
	private function registerScene(scene:IScene) {
		scenes.set(scene.getName(), scene);
	}
	
	public function startup() {
        startAppTime = Date.now().getTime();
		prevTime = Lib.getTimer();
				
		Lib.current.addEventListener(Event.ENTER_FRAME, onEnterFrame);
		
		setScene(ConnectScene.NAME, {networkMonitor: networkMonitor});
	}
	
	public function setScene(sceneName:String, data:Dynamic = null) {
		if ( currentScene != null ) {
			var contentRoot = currentScene.getContentRoot();
			Lib.current.removeChild(contentRoot);
			
			currentScene.clear();
		}
			
		currentScene = scenes.get(sceneName);
		
		if ( currentScene != null ) {
			currentScene.init(data);

			var contentRoot = currentScene.getContentRoot();
			if ( contentRoot != null )
				Lib.current.addChild(contentRoot);
		}
	}
	
	private function onEnterFrame(e:Event)
	{
		var currentTime:Int = Lib.getTimer();
		var deltaTime:Int = currentTime - prevTime;
		prevTime = currentTime;

		if ( currentScene != null ) {
			currentScene.update(deltaTime);
		}
	}
    
    public static function getStartAppTime():Float {
        return startAppTime;
    }
		
	static function main() {
		
		#if (flash9 || flash10)
			haxe.Log.trace = function(v,?pos) { untyped __global__["trace"](pos.className+"#"+pos.methodName+"("+pos.lineNumber+"):",v); }
		#elseif flash
			haxe.Log.trace = function(v,?pos) { flash.Lib.trace(pos.className+"#"+pos.methodName+"("+pos.lineNumber+"): "+v); }
		#end
		
		var main = Main.getInstance();
		main.startup();
	}
}
